package com.shenjinzheng.sso.service.impl.member;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenjinzheng.member.api.MemberInfoClient;
import com.shenjinzheng.member.entity.MemberInfo;
import com.shenjinzheng.sso.dto.MemberLoginDTO;
import com.shenjinzheng.sso.entity.Member;
import com.shenjinzheng.sso.mapper.MemberMapper;
import com.shenjinzheng.sso.service.MemberAuthService;
import com.shenjinzheng.sso.service.MemberService;
import com.shenjinzheng.sso.utils.JwtUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class MemberServiceImplByCode extends ServiceImpl<MemberMapper, Member> implements MemberAuthService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private MemberService memberService;

    @Resource
    private MemberInfoClient memberInfoClient;

    @Override
    public String login(MemberLoginDTO memberLoginDTO) {
        log.info("手机验证码登录方式...");
        //用户在页面输入的手机号
        String phoneInPage = memberLoginDTO.getPhone();
        log.info("phoneInPage:{}", phoneInPage);
        //用户在页面输入的短信验证码
        String codeInPage = memberLoginDTO.getCode();
        log.info("codeInPage:{}", codeInPage);
        //缓存在Redis的短信验证码,有效期为5分钟
        String key = "robot:sso:loginCode:" + phoneInPage;
        String codeInRedis = redisTemplate.opsForValue().get(key);
        log.info("codeInRedis:{}", codeInRedis);
        //进行校验
        if (codeInRedis == null || !codeInRedis.equals(codeInPage)) {
            //如果codeInRedis为空或者缓存的验证码和用户输入的不一致 -> 登录失败 -> 提示验证码错误
            throw new RuntimeException("验证码错误");
        }
        /*
        代码运行到此 -> 接着判断用户是否新用户,实现登录即注册逻辑,不是新用户则到此已经登录成功
         */
        Member member = this.lambdaQuery()
                .eq(Member::getPhone, phoneInPage)
                .one();
        if (member == null) {
            //如果member为空 -> 是新用户,自动完成注册(存在member表中)
            member = new Member();
            member.setPhone(phoneInPage);
            //存入新用户
            memberService.save(member);

            MemberInfo memberInfo=new MemberInfo();
            memberInfo.setId(member.getId());
            memberInfo.setPhone(member.getPhone());
            memberInfoClient.save(memberInfo);
        }
        //登录成功后要删除再Redis中缓存的code,因为不需要了
        redisTemplate.delete(key);
        //签发token
        HashMap<String,Object> map=new HashMap<>();
        map.put("id",member.getId());
        String token = jwtUtil.createToken(map);
        return token;
    }

    @Override
    public String getCode(String phone) {
        Random r = new Random();
        String code = r.nextInt(8888) + 1000 + "";
        String key = "robot:sso:loginCode:" + phone;
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);
        //往MQ推送消息
        rabbitTemplate.convertAndSend("direct_exchange", "sms", "你的登录验证码为:" + code);
        return code;
    }
}
